home *** CD-ROM | disk | FTP | other *** search
- #ifndef __TIME_CC
- #define __TIME_CC
- #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
- /***************************************************************************
- *
- * time.cc - Definitions for the Standard Library time facets
- *
- *
- ***************************************************************************
- *
- * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
- * ALL RIGHTS RESERVED *
- * The software and information contained herein are proprietary to, and
- * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
- * intends to preserve as trade secrets such software and information.
- * This software is furnished pursuant to a written license agreement and
- * may be used, copied, transmitted, and stored only in accordance with
- * the terms of such license and with the inclusion of the above copyright
- * notice. This software and information or any other copies thereof may
- * not be provided or otherwise made available to any other person.
- *
- * Notwithstanding any other lease or license that may pertain to, or
- * accompany the delivery of, this computer software and information, the
- * rights of the Government regarding its use, reproduction and disclosure
- * are as set forth in Section 52.227-19 of the FARS Computer
- * Software-Restricted Rights clause.
- *
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
- * Technical Data and Computer Software clause at DFARS 252.227-7013.
- * Contractor/Manufacturer is Rogue Wave Software, Inc.,
- * P.O. Box 2328, Corvallis, Oregon 97339.
- *
- * This computer software and information is distributed with "restricted
- * rights." Use, duplication or disclosure is subject to restrictions as
- * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
- * Computer Software-Restricted Rights (April 1985)." If the Clause at
- * 18-52.227-74 "Rights in Data General" is specified in the contract,
- * then the "Alternate III" clause applies.
- *
- **************************************************************************/
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- using namespace std;
- #endif
-
- // --------------------------------------
- // Template time_reader member templates.
- // --------------------------------------
-
- template <class charT,class InputIterator>
- time_reader<charT,InputIterator>::time_reader
- (InputIterator& in,InputIterator& end,ios_base& io):
- digit_reader<charT,InputIterator>(in,end,io),
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- timp(use_facet<timepunct<charT> >(io.getloc()))
- #else
- // timp(use_facet(io.getloc(),(timepunct<charT>*)0))
- timp(ms_idiocy(io))
- #endif
- {
- // Don't recognize signs on any numeric input.
- this->is_signed=false;
- }
-
- template <class charT,class InputIterator>
- bool time_reader<charT,InputIterator>::
- get_time_pattern (const string_type &patt,tm *time)
- {
- enum {
- edit_year = 0x01,
- edit_month = 0x02,
- edit_century = 0x04
- };
-
- int post_edits=0;
- const charT *p=patt.c_str(),*patt_end=p+patt.length();
- for ( ; p<patt_end; p++) {
- switch (this->ctyp.narrow(*p,' ')) {
- case '%':
- {
- int *iresult;
- const keyword_map<charT> *keywords=NULL;
-
- switch (this->ctyp.narrow(*++p,' ')) {
- case 'a':
- case 'A':
- // Day of week (abbreviated or not).
- keywords=&get_day_map(timp);
- iresult=&time->tm_wday;
- break;
- case 'b':
- case 'B':
- // Month name (abbreviated or not).
- keywords=&get_month_map(timp);
- iresult=&time->tm_mon;
- break;
- case 'm':
- // Numeric month, comes in 1 higher than the number we want.
- post_edits|=edit_month;
- iresult=&time->tm_mon;
- break;
- case 'c':
- // Full date, time and year in default format.
- return get_time_pattern(get_patt_string(timp,2),time);
- case 'd':
- // Day of month.
- iresult=&time->tm_mday;
- break;
- case 'H':
- // Hours.
- iresult=&time->tm_hour;
- break;
- case 'M':
- // Minutes.
- iresult=&time->tm_min;
- break;
- case 'S':
- // Seconds.
- iresult=&time->tm_sec;
- break;
- case 'Y':
- // Year with Century.
- post_edits|=edit_year;
- iresult=&time->tm_year;
- break;
- case 'y':
- // 2-digit Year without Century.
- post_edits|=(edit_year|edit_century);
- iresult=&time->tm_year;
- break;
- default:
- // All other format characters are not supported on input.
- return false;
- }
-
- if (keywords) {
- if ((*iresult=get_keyword(*keywords))<0)
- return false;
- } else
- *iresult=to_ulong(this->get_int_digits());
- }
- break;
-
- default:
- if (!this->at_end() && *this->in==*p)
- this->in++;
- else
- return false;
- }
-
- if (this->error)
- return false;
- }
-
- if (post_edits&edit_year)
- if (post_edits&edit_century && time->tm_year<100)
- ; // 2-digit year is already relative to 1900
- else
- time->tm_year-=1900;
-
- if (post_edits&edit_month)
- time->tm_mon--;
-
- return true;
- }
-
-
- #ifndef _RWSTD_NO_NAMESPACE
- } namespace std {
- #endif
-
-
- // -----------------------------------------------------
- // Facet time_get<charT,InputIterator> member templates.
- // -----------------------------------------------------
-
- template <class charT, class InputIterator>
- locale::id time_get<charT,InputIterator>::id;
-
- template <class charT, class InputIterator>
- time_get<charT,InputIterator>::~time_get() { }
-
- template <class charT, class InputIterator>
- time_base::dateorder time_get<charT,InputIterator>::do_date_order () const
- {
- // We would prefer to return a value that matches the date format defined
- // in the timepunct facet in the caller's locale, but we can't get there
- // from here ...
- return no_order;
- }
-
- template <class charT, class InputIterator>
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_time (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io);
- err=ios_base::goodbit;
-
- // Parse according to pattern 1 (strftime '%X' -- default time pattern)
- if (!reader.get_time_pattern(reader.get_patt_string(reader.timp,1),time))
- err=ios_base::failbit;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_date (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io);
- err=ios_base::goodbit;
-
- // Parse according to pattern 0 (strftime '%x' -- default date pattern)
- if (!reader.get_time_pattern(reader.get_patt_string(reader.timp,0),time))
- err=ios_base::failbit;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_weekday (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io);
- int wd=reader.get_keyword(reader.get_day_map(reader.timp));
- err=ios_base::goodbit;
-
- if (wd<0)
- err=ios_base::failbit;
- else
- time->tm_wday=wd;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_monthname (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io);
- int mo=reader.get_keyword(reader.get_month_map(reader.timp));
- err=ios_base::goodbit;
-
- if (mo<0)
- err=ios_base::failbit;
- else
- time->tm_mon=mo;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_year (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io);
- int yr=reader.to_ulong(reader.get_int_digits());
- err=ios_base::goodbit;
-
- // 2-digit year numbers are accepted, but are not treated specially, and so
- // end up in the 1st century C.E.
- if (reader.error)
- err=ios_base::failbit;
- else
- time->tm_year=yr-1900;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- // -----------------------------------------------------
- // Facet time_put<charT,InputIterator> member templates.
- // -----------------------------------------------------
-
- template <class charT, class OutputIterator>
- locale::id time_put<charT,OutputIterator>::id;
-
- template <class charT, class OutputIterator>
- time_put<charT,OutputIterator>::~time_put() { }
-
- template <class charT, class OutputIterator>
- OutputIterator time_put<charT,OutputIterator>::put
- (OutputIterator out, ios_base &io, charT fill, const tm *time,
- const charT* pattern, const charT* patt_end) const
- {
- size_t patt_len=patt_end-pattern;
- char scratch[40];
- char *narrow_patt=(patt_len<=sizeof scratch)? scratch : new char[patt_len];
-
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- use_facet<ctype<charT> >(io.getloc()).narrow(pattern,patt_end,' ',narrow_patt);
- #else
- use_facet(io.getloc(),(ctype<charT>*)0).narrow(pattern,patt_end,' ',narrow_patt);
- #endif
-
- char *np=narrow_patt;
- for (const charT* wp=pattern; wp<patt_end; wp++,np++)
- if (*np!='%')
- *out++=*wp;
- else if (++wp<patt_end)
- switch (*++np) {
-
- case 'O':
- // POSIX-style modifier
- if (++wp<patt_end)
- out=do_put(out,io,fill,time,*++np,'O');
- break;
-
- case '%':
- // Literal percent sign
- *out++=*wp;
- break;
-
- default:
- // Treat everything else as a time format specifier.
- out=do_put(out,io,fill,time,*np,' ');
- }
-
- if (narrow_patt!=scratch)
- delete[] narrow_patt;
-
- return out;
- }
-
- template <class charT, class OutputIterator>
- OutputIterator time_put<charT,OutputIterator>::do_put
- (OutputIterator out, ios_base &io, charT fill, const tm *time,
- char format, char modifier) const
- {
- const __RWSTD::timepunct<charT>& timp =
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- use_facet<__RWSTD::timepunct<charT> >(io.getloc());
- #else
- use_facet(io.getloc(),(__RWSTD::timepunct<charT>*)0);
- #endif
-
- static const char do_as_pattern[]="xXcDrT";
- const char *p=strchr(do_as_pattern,format);
- if (p) {
- // Catch formats implemented as calls to the pattern-based method before
- // going to the expense of constructing a digit_writer.
- unsigned i=p-do_as_pattern;
- const _TYPENAME __RWSTD::timepunct<charT>::string_type& s =
- __RWSTD::keyword_cracker<charT>::get_patt_string(timp,i);
- return put(out,io,fill,time,s.c_str(),s.c_str()+s.length());
- }
-
- __RWSTD::digit_writer<charT,OutputIterator> writer(out,io);
- writer.width=0;
-
- if (modifier=='O') {
- // Uppercase letter O (not zero) -- requests ordinal string if defined.
- int n,m;
- switch (format) {
- case 'C':
- // Exclusive Rogue Wave extension, let's you announce, "Welcome to the
- // %OC century!" (See note on unmodified 'C' below.)
- n=(time->tm_year+1999)/100;
- break;
- case 'd':
- case 'e':
- n=time->tm_mday;
- break;
- case 'H':
- n=time->tm_hour+1;
- break;
- case 'I':
- n=time->tm_hour+1;
- if (n>12)
- n-=12;
- break;
- case 'm':
- n=time->tm_mon+1;
- break;
- case 'M':
- n=time->tm_min+1;
- break;
- case 'S':
- n=time->tm_sec+1;
- break;
- case 'u':
- n=time->tm_wday;
- if (n==0) n=7;
- break;
- case 'w':
- n=time->tm_wday;
- break;
- case 'U':
- n=(time->tm_yday)/7;
- break;
- case 'W':
- m=time->tm_wday-1; // Monday-based day of week
- if (m<0) m+=7;
- n=(time->tm_yday-m)/7;
- break;
- case 'y':
- n=(time->tm_year%100)+1;
- break;
- default:
- n=999; // Cause error output.
- }
-
- writer.put_keyword(writer.get_ord_string(timp,n),fill);
-
- } else {
- bool abbrev=false;
- const _TYPENAME __RWSTD::timepunct<charT>::string_type *s=NULL;
- // _TYPENAME __RWSTD::timepunct<charT>::string_type tzs;
- int n;
-
- writer.radix=10;
- writer.separable=false;
-
- switch (format) {
- case 'a':
- abbrev=true;
- case 'A':
- // Week day name or abbreviation.
- s=&writer.get_day_string(timp,time->tm_wday,abbrev);
- break;
-
- case 'b':
- case 'h':
- abbrev=true;
- case 'B':
- // Month name or abbreviation.
- s=&writer.get_month_string(timp,time->tm_mon,abbrev);
- break;
-
- case 'C':
- // Century. Note that we begin the 20th century in 1901, not 1900. The
- // draft standard does not seem to address this controversy.
- n=(time->tm_year+1999)/100;
- break;
-
- case 'd':
- // Day of month with leading zero.
- writer.iprecision=2;
- case 'e':
- // Day of month with leading blank.
- n=time->tm_mday;
- writer.width=2;
- break;
-
- case 'H':
- // Hour (24-hour clock).
- n=time->tm_hour;
- writer.iprecision=2;
- break;
-
- case 'I':
- // Hour (12-hour clock, caller must append am/pm to resolve ambiguity).
- n=time->tm_hour;
- if (n==0)
- n=12;
- else if (n>12)
- n-=12;
- writer.iprecision=2;
- break;
-
- case 'j':
- // 3-digit day of year.
- n=time->tm_yday+1;
- writer.iprecision=3;
- break;
-
- case 'm':
- // Month number.
- n=time->tm_mon+1;
- writer.iprecision=2;
- break;
-
- case 'M':
- // Minutes.
- n=time->tm_min;
- writer.iprecision=2;
- break;
-
- case 'n':
- // Newline character.
- *out++=writer.ctyp.widen('\n');
- break;
-
- case 'p':
- // ante/post meridian string.
- s=&writer.get_ampm_string(timp,time->tm_hour==0 || time->tm_hour>12);
- break;
-
- case 'S':
- // Seconds.
- n=time->tm_sec;
- writer.iprecision=2;
- break;
-
- case 't':
- // Tab character.
- *out++=writer.ctyp.widen('\t');
- break;
-
- case 'u':
- // Weekday (1-7, 1==Monday)
- n=time->tm_wday;
- if (n==0)
- n=7;
- break;
-
- case 'U':
- // Week number of year (assuming weeks start on Sunday).
- n=(time->tm_yday)/7;
- writer.iprecision=2;
- break;
-
- case 'w':
- // Weekday (0-6, 0==Sunday).
- n=time->tm_wday;
- break;
-
- case 'W':
- // Week number of year (assuming weeks start on Monday).
- n=(time->tm_yday+(time->tm_wday==0? 6 : (time->tm_wday-1)))/7;
- writer.iprecision=2;
- break;
-
- case 'y':
- // Year without century.
- n=time->tm_year%100;
- writer.iprecision=2;
- break;
-
- case 'Y':
- // Year with century.
- n=time->tm_year+1900;
- break;
-
- case 'Z':
- // Time zone name
- // tzs = __RWSTD::timepunct<charT>::string_type(
- // writer.ctyp.widen(tzname[time->tm_isdst ? 1 : 0]));
- // s = &tzs;
- break;
-
- default:
- // Everything else is an error.
- s=&writer.get_day_string(timp,99,false);
- }
-
- if (s)
- writer.put_keyword(*s,fill);
- else {
- writer.digitize((unsigned long) n);
- writer.put_digits(fill);
- }
- }
-
- return out;
- }
-
-
- // --------------------------------------------------------------------
- // Time input by-name member templates: time_get<charT,InputIterator>
- // --------------------------------------------------------------------
-
- template <class charT, class InputIterator >
- time_get_byname<charT, InputIterator>::time_get_byname
- (const char* /*name*/, size_t refs): time_get<charT,InputIterator>(refs)
- { }
-
- template <class charT, class InputIterator>
- time_get_byname<charT, InputIterator>::~time_get_byname()
- { }
-
- // --------------------------------------------------------------------
- // Time output by-name member templates: time_put<charT,InputIterator>
- // --------------------------------------------------------------------
-
- template <class charT, class OutputIterator>
- time_put_byname<charT,OutputIterator>::time_put_byname
- (const char* /*name*/, size_t refs): time_put<charT,OutputIterator>(refs)
- { }
-
- template <class charT, class OutputIterator>
- time_put_byname<charT,OutputIterator>::~time_put_byname()
- { }
-
-
- #ifndef _RWSTD_NO_NAMESPACE
- }
- #endif
-
- #pragma option pop
- #endif /* __TIME_CC */
-